<!DOCTYPE html>
<html>
<head>
    <title>Electromagnetic Field Diagram</title>
    <style>
        canvas {
            border: 1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas id="physicsCanvas" width="600" height="450"></canvas>
    <script>
        const canvas = document.getElementById('physicsCanvas');
        const ctx = canvas.getContext('2d');

        // Style settings
        ctx.strokeStyle = 'black';
        ctx.fillStyle = 'black';
        ctx.lineWidth = 1.5;

        // Center point (where the wire touches the ground)
        const cx = canvas.width / 2;
        const cy = 220;

        // --- Helper function to draw a line with an arrowhead ---
        function drawArrow(ctx, fromX, fromY, toX, toY, headSize) {
            // Draw the line segment
            ctx.beginPath();
            ctx.moveTo(fromX, fromY);
            ctx.lineTo(toX, toY);
            ctx.stroke();

            // Draw the arrowhead
            const angle = Math.atan2(toY - fromY, toX - fromY);
            ctx.beginPath();
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headSize * Math.cos(angle - Math.PI / 6), toY - headSize * Math.sin(angle - Math.PI / 6));
            ctx.moveTo(toX, toY);
            ctx.lineTo(toX - headSize * Math.cos(angle + Math.PI / 6), toY - headSize * Math.sin(angle + Math.PI / 6));
            ctx.stroke();
        }

        // --- 1. Draw Ground ---
        // Main ground surface line
        ctx.beginPath();
        ctx.moveTo(0, cy);
        ctx.lineTo(canvas.width, cy);
        ctx.stroke();

        // Ground hatching
        ctx.save();
        ctx.lineWidth = 1;
        ctx.strokeStyle = '#444';
        for (let x = 0; x < canvas.width; x += 15) {
            ctx.beginPath();
            ctx.moveTo(x, cy);
            ctx.lineTo(x - 10, cy + 10);
            ctx.stroke();
        }
        ctx.restore();
        
        // --- 2. Draw Wire ---
        const wireWidth = 8;
        const wireHeight = 180;
        const wireTopY = cy - wireHeight;
        
        // Wire body (rectangle)
        ctx.beginPath();
        ctx.rect(cx - wireWidth / 2, wireTopY, wireWidth, wireHeight);
        ctx.fillStyle = 'white';
        ctx.fill();
        ctx.stroke();

        // Hatching inside the wire
        ctx.save();
        ctx.lineWidth = 1;
        for (let y = cy; y > wireTopY + 4; y -= 6) {
            ctx.beginPath();
            ctx.moveTo(cx - wireWidth / 2, y);
            ctx.lineTo(cx + wireWidth / 2, y);
            ctx.stroke();
        }
        ctx.restore();

        // --- 3. Draw Current 'I' and its Arrow ---
        const currentArrowX = cx + 40;
        const currentArrowY = cy - 110;
        ctx.font = 'italic 22px Times New Roman';
        ctx.fillText('I', currentArrowX + 15, currentArrowY + 8);
        
        // Draw the arrow for current I
        ctx.beginPath();
        ctx.moveTo(currentArrowX, currentArrowY - 12);
        ctx.lineTo(currentArrowX, currentArrowY + 12);
        ctx.lineTo(currentArrowX - 5, currentArrowY + 5);
        ctx.moveTo(currentArrowX, currentArrowY + 12);
        ctx.lineTo(currentArrowX + 5, currentArrowY + 5);
        ctx.stroke();


        // --- 4. Draw Semi-circular Field in the Ground ---
        const outerRadius = 130;
        const innerRadius1 = 50;
        const innerRadius2 = 90;

        // Outer semi-circular boundary
        ctx.beginPath();
        ctx.arc(cx, cy, outerRadius, 0, Math.PI, false);
        ctx.stroke();

        // Inner semi-circular equipotential lines
        ctx.beginPath();
        ctx.arc(cx, cy, innerRadius1, 0, Math.PI, false);
        ctx.stroke();
        ctx.beginPath();
        ctx.arc(cx, cy, innerRadius2, 0, Math.PI, false);
        ctx.stroke();

        // Radial field lines with arrows
        const numLines = 9;
        for (let i = 0; i < numLines; i++) {
            // Distribute angles from 0 to PI, inset from the edges
            const angle = (Math.PI / (numLines + 1)) * (i + 1); 
            const lineEndX = cx + outerRadius * Math.cos(angle);
            const lineEndY = cy + outerRadius * Math.sin(angle);
            
            // Draw a line from center to edge with an arrowhead
            drawArrow(ctx, cx, cy, lineEndX, lineEndY, 12);
        }
        
        // --- 5. Draw Labels 'a' and 'b' ---
        ctx.font = 'italic 24px Times New Roman';
        ctx.fillText('a', cx - 70, cy - 10);
        ctx.fillText('b', cx - 110, cy - 10);

        // --- 6. Draw Caption ---
        ctx.font = '22px "SimSun", "Songti SC", serif';
        ctx.textAlign = 'center';
        ctx.fillText('习题 8-4 图', cx, cy + outerRadius + 60);

    </script>
</body>
</html>